/*
 * Copyright 2011 Christoph Ludwig (christoph[at]chludwig.de). All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package de.chludwig.ehumanities.provenance.persistence;

import java.io.File;
import java.util.Date;
import java.util.UUID;

import de.chludwig.ehumanities.provenance.background.ZipArchiveTask;
import de.chludwig.ehumanities.provenance.exception.ProvenanceFileNotFoundException;
import de.chludwig.ehumanities.provenance.utils.FileUtil;

/**
 * 
 */
public class ArchivePO {

  public static final String ZIP_FILE_EXTENSION = ".zip";

  private StorageArea storageArea;
  private UUID archiveId;
  private File archiveFolder;

  /**
   * @param archiveId
   * @param dataFolder
   * @return
   */
  public static File constructZipArchiveFile(File archiveContainerFolder) {
    String zipArchiveName = archiveContainerFolder.getName() + ZIP_FILE_EXTENSION;
    File archiveFolder = archiveContainerFolder.getParentFile();
    return new File(archiveFolder, zipArchiveName);
  }

  public ArchivePO(StorageArea storageArea, UUID archiveId) {
    this.storageArea = storageArea;
    this.archiveId = archiveId;
    this.archiveFolder = null;
  }

  /**
   * @return the storageArea
   */
  public StorageArea getStorageArea() {
    return storageArea;
  }

  /**
   * @return the archiveId
   */
  public UUID getArchiveId() {
    return archiveId;
  }

  /**
   * @return the archiveFolder
   */
  public File getArchiveFolder() {
    if(archiveFolder == null) {
      File archivesFolder = storageArea.getArchivesFolder();
      archiveFolder = new File(archivesFolder, archiveId.toString());
    }
    return archiveFolder;
  }

  /**
   * @return the zipFile
   */
  public File getZipFile() {
    File archiveContainerFolder = getArchiveFolder();
    return constructZipArchiveFile(archiveContainerFolder);
  }

  public ZipArchiveTask getZipTask() {
    return new ZipArchiveTask(getArchiveFolder(), getZipFile());
  }
  
  public void sweepIfStale(Date cutoffTimestamp) {
    File containerFolder = getArchiveFolder();
    File zip = getZipFile();
    
    long cutoffMillisSinceEpoch = cutoffTimestamp.getTime();
    boolean zipModified = zip.isFile() && FileUtil.treeModifiedSince(zip, cutoffMillisSinceEpoch);
    boolean containerModified = FileUtil.treeModifiedSince(containerFolder, cutoffMillisSinceEpoch);
    
    if (!(zipModified || containerModified)) {
      File tempDataFolder = getStorageArea().getTmpFolder();
      if (zip.isFile()) {
        File tmpZip = new File(tempDataFolder, zip.getName());
        zip.renameTo(tmpZip);
        FileUtil.deleteRecursively(tmpZip);
      }
      File tmpContainer = new File(tempDataFolder, containerFolder.getName());
      containerFolder.renameTo(tmpContainer);
      FileUtil.deleteRecursively(tmpContainer);
    }
  }

  public void checkReadWritableArchiveFolder() {
    File containerArchiveFolder = getArchiveFolder();
    if (!(containerArchiveFolder.isDirectory() && containerArchiveFolder.canRead() && containerArchiveFolder.canWrite())) {
      String msg = "zip folder " + containerArchiveFolder + " does not exist or is not a read- and writeable directory";
      throw new ProvenanceFileNotFoundException(msg, null);
    }
  }

}
